package com.shanshui

import org.gradle.api.Plugin;
import org.gradle.api.Project

import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream;

/**
 * @author mashanshui
 * @date 2025-07-23
 * @desc TODO
 */
class AnnotationExecutorPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        println("AnnotationExecutorPlugin")
//        project.afterEvaluate {
//            boolean isProcessResourcesTask = false
//            //1. 找到 ProcessXXXResources 这个task
//            def processResSet = project.tasks.findAll {
//                project.android.applicationVariants.all {
//                    variant ->
//                        if (it.name == 'process' + variant.getName() + 'Resources') {
//                            isProcessResourcesTask = true
//                        }
//                }
//                return isProcessResourcesTask
//            }
//            if (!isProcessResourcesTask) {
//                return
//            }
//            //2. 将我们的自定义脚本放在 ProcessAndroidResources 这个task之后执行
//            for (def processRes in processResSet) {
//                processRes.doLast {
//                    File[] fileList = getResPackageOutputFolder().listFiles()
//                    for (def i = 0; i < fileList.length; i++) {
//                        //3. 找到 .ap_ 文件
//                        if (fileList[i].isFile() && fileList[i].path.endsWith(".ap_")) {
//                            File packageOutputFile = fileList[i]
//                            //4. 解压 .ap_ 文件
//                            int prefixIndex = packageOutputFile.path.lastIndexOf(".")
//                            String unzipPath = packageOutputFile.path.substring(0, prefixIndex) + File.separator
//                            unZip(packageOutputFile, unzipPath)
//                            //5. 解析  resources.arsc 文件，并进行图片去重操作
////                            imageOptimize(unzipPath)
//                            //6. 将 解压后的文件重新打包成 .ap_ zip压缩包
//                            zipFolder(unzipPath, packageOutputFile.path)
//
//                        }
//                    }
//
//
//                }
//            }
//        }
    }

//    void imageOptimize(String resourcePath) {
//        // 1. 遍历 res 目录下的图片，根据 md5 寻找重复图片，并记录在 map 中，map的key为 md5，value为图片数据，文件遍历和md5计算比较简单，就不贴代码了。
//        HashMap<String, ArrayList <DuplicatedEntry>> duplicatedResources = findDuplicatedResources(resourcePath);
//        File arscFile = new File(resourcePath+ 'resources.arsc')
//
//        if (arscFile.exists()) {
//            FileInputStream arscStream = null;
//
//            //ResourceFile是 android-chunk-utils里面定义的数据结构
//            ResourceFile resourceFile = null;
//            try {
//                arscStream = new FileInputStream(arscFile);
//
//                resourceFile = ResourceFile.fromInputStream(arscStream);
//                //1. 调用ResourceFile的getChunks方法，就能将arsc流转换成Chunk对象树
//                List<Chunk> chunks = resourceFile.getChunks();
//
//                HashMap<String, String> toBeReplacedResourceMap = new HashMap<String, String>(1024);
//
//                Iterator<Map.Entry<String, ArrayList<DuplicatedEntry>>> iterator = duplicatedResources.entrySet().iterator();
//                //2. 遍历 duplicatedResources 中记录的重复图片，其实这一步也可以在 findDuplicatedResources 的时候就做了
//                while (iterator.hasNext()) {
//                    Map.Entry<String, ArrayList<DuplicatedEntry>> duplicatedEntry = iterator.next();
//                    // 保留第一个资源，索引从1开始，其他资源删除掉
//                    for (def index = 1; index < duplicatedEntry.value.size(); ++index) {
//                        // 删除图片，并将删除的图片信息保存在 toBeReplacedResourceMap 这个数据结构中
//                        removeZipEntry(apFile, duplicatedEntry.value.get(index).name);
//                        toBeReplacedResourceMap.put(duplicatedEntry.value.get(index).name, duplicatedEntry.value.get(0).name);
//                    }
//                }
//
//                //3. 更新 resources.arsc 中的数据
//                for (def index = 0; index < chunks.size(); ++index) {
//                    Chunk chunk = chunks.get(index);
//                    if (chunk instanceof ResourceTableChunk) {
//                        ResourceTableChunk resourceTableChunk = (ResourceTableChunk) chunk;
//                        //3. 找到字符串常量池,也是直接调用getStringPool方法即可，StringPoolChunk 也是android-chunk-utils工具中定义好的数据结构，直接使用就行
//                        StringPoolChunk stringPoolChunk  = resourceTableChunk.getStringPool();
//                        for (def i = 0; i < stringPoolChunk.stringCount; ++i) {
//                            //遍历字符串常量池的值，如果值和toBeReplacedResourceMap中包含的值相等，则进行替换
//                            def key = stringPoolChunk.getString(i);
//                            if (toBeReplacedResourceMap.containsKey(key)) {
//                                stringPoolChunk.setString(i, toBeReplacedResourceMap.get(key));
//                            }
//                        }
//                    }
//                }
//            } catch (IOException ignore) {
//            } catch (FileNotFoundException ignore) {
//            } finally {
//                if (arscStream != null) {
//                    IOUtils.closeQuietly(arscStream);
//                }
//            }
//        }
//
//    }

// 文件的解压和压缩实现如下
    def unZip(File src, String savepath) throws IOException {
        def count = -1;
        def index = -1;
        def flag = false;
        def file1 = null;
        def is = null;
        def fos = null;
        def bos = null;

        ZipFile zipFile = new ZipFile(src);
        Enumeration<?> entries = zipFile.entries();

        while (entries.hasMoreElements()) {
            def buf = new byte[2048];
            ZipEntry entry = (ZipEntry) entries.nextElement();
            def filename = entry.getName();

            filename = savepath + filename;
            File file2 = file(filename.substring(0, filename.lastIndexOf('/')));

            if (!file2.exists()) {
                file2.mkdirs()
            }

            if (!filename.endsWith("/")) {

                file1 = file(filename);
                file1.createNewFile();
                is = zipFile.getInputStream(entry);
                fos = new FileOutputStream(file1);
                bos = new BufferedOutputStream(fos, 2048);

                while ((count = is.read(buf)) > -1) {
                    bos.write(buf, 0, count);
                }

                bos.flush();

                fos.close();
                is.close();

            }
        }

        zipFile.close();

    }

    def zipFolder(String srcPath, String savePath) throws IOException {
        def saveFile = file(savePath)
        saveFile.delete()
        saveFile.createNewFile()
        def outStream = new ZipOutputStream(new FileOutputStream(saveFile))
        def srcFile = file(srcPath)
        zipFile(srcFile.getAbsolutePath() + File.separator, "", outStream)
        outStream.finish()
        outStream.close()
    }

    def zipFile(String folderPath, String fileString, ZipOutputStream out) throws IOException {
        File srcFile = file(folderPath + fileString)
        if (srcFile.isFile()) {
            def zipEntry = new ZipEntry(fileString)
            def inputStream = new FileInputStream(srcFile)
            out.putNextEntry(zipEntry)
            def len
            def buf = new byte[2048]
            while ((len = inputStream.read(buf)) != -1) {
                out.write(buf, 0, len)
            }
            out.closeEntry()
        } else {
            def fileList = srcFile.list()
            if (fileList.length <= 0) {
                def zipEntry = new ZipEntry(fileString + File.separator)
                out.putNextEntry(zipEntry)
                out.closeEntry()
            }

            for (def i = 0; i < fileList.length; i++) {
                zipFile(folderPath, fileString.equals("") ? fileList[i] : fileString + File.separator + fileList[i], out)
            }
        }
    }

}

